package com.yiren.dbaa.module.device.view.activity;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.yiren.backstage.communication.analysis.GyroDataAnalysis;
import com.yiren.backstage.communication.interfaces.DataCallback;
import com.yiren.backstage.config.api.LoadConfigApi;
import com.yiren.backstage.config.bean.device.DeviceStudyConfigBean;
import com.yiren.dbaa.R;
import com.yiren.dbaa.activity.BaseActivity;
import com.yiren.backstage.communication.utils.ArrayConvertUtil;
import com.yiren.backstage.communication.utils.ZiyanGyroGearUtil;
import com.yiren.dbaa.module.device.view.ZiyanGyroPointView;
import com.yiren.dbaa.module.param_config.api.ParamConfigApi;
import com.yiren.dbaa.view.toast.MessageBox;

import org.apache.commons.lang.StringUtils;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

/**
 * Created by WANGRONGXIANG
 * on 2021/10/25
 * Describe 机械档位档位区域学习
 */
public class GearsZiyanActivity extends BaseActivity implements ZiyanGyroGearUtil.OnZiyanDataListener {

    @BindView(R.id.button_g1)
    TextView buttonG1;
    @BindView(R.id.edit_min_x1)
    EditText editMinX1;
    @BindView(R.id.edit_max_x1)
    EditText editMaxX1;
    @BindView(R.id.edit_min_y1)
    EditText editMinY1;
    @BindView(R.id.edit_max_y1)
    EditText editMaxY1;
    @BindView(R.id.button_g2)
    TextView buttonG2;
    @BindView(R.id.edit_min_x2)
    EditText editMinX2;
    @BindView(R.id.edit_max_x2)
    EditText editMaxX2;
    @BindView(R.id.edit_min_y2)
    EditText editMinY2;
    @BindView(R.id.edit_max_y2)
    EditText editMaxY2;
    @BindView(R.id.button_g3)
    TextView buttonG3;
    @BindView(R.id.edit_min_x3)
    EditText editMinX3;
    @BindView(R.id.edit_max_x3)
    EditText editMaxX3;
    @BindView(R.id.edit_min_y3)
    EditText editMinY3;
    @BindView(R.id.edit_max_y3)
    EditText editMaxY3;
    @BindView(R.id.button_g4)
    TextView buttonG4;
    @BindView(R.id.edit_min_x4)
    EditText editMinX4;
    @BindView(R.id.edit_max_x4)
    EditText editMaxX4;
    @BindView(R.id.edit_min_y4)
    EditText editMinY4;
    @BindView(R.id.edit_max_y4)
    EditText editMaxY4;
    @BindView(R.id.button_g5)
    TextView buttonG5;
    @BindView(R.id.edit_min_x5)
    EditText editMinX5;
    @BindView(R.id.edit_max_x5)
    EditText editMaxX5;
    @BindView(R.id.edit_min_y5)
    EditText editMinY5;
    @BindView(R.id.edit_max_y5)
    EditText editMaxY5;
    @BindView(R.id.button_g6)
    TextView buttonG6;
    @BindView(R.id.edit_min_x6)
    EditText editMinX6;
    @BindView(R.id.edit_max_x6)
    EditText editMaxX6;
    @BindView(R.id.edit_min_y6)
    EditText editMinY6;
    @BindView(R.id.edit_max_y6)
    EditText editMaxY6;
    @BindView(R.id.point_view)
    ZiyanGyroPointView pointView;
    @BindView(R.id.text_x)
    TextView textX;
    @BindView(R.id.text_y)
    TextView textY;
    @BindView(R.id.text_g)
    TextView textG;
    private TextView[] buttonG;
    private EditText[] editMinX;
    private EditText[] editMaxX;
    private EditText[] editMinY;
    private EditText[] editMaxY;
    private boolean isReset;   //是否重置差值
    private String gyroData;   //档位数据
    private float resetX = 0;  //重置差值后的X值
    private float resetY = 0;  //重置差值后的Y值
    private final String SEPARATOR = ":";
    private final int expandBoundaryValue = 30;  //拓展档位边界值，使最左边的档位无左边界，最右边的档位无有边界，最上边的档位无上边界，最下边的档位无下边界
    private final float expandCenterY = 0.15f;   //拓展中间Y值的比例（上面区域向下移，下面区域向上移的比例）

    private StudyRunnable[] studyRun;
    private float[][] xys = new float[6][4];
    private List<Float> xPoints = new ArrayList<>();  //x位置集合，记录档位轨迹，最多保存5个点
    private List<Float> yPoints = new ArrayList<>();  //y位置集合，记录档位轨迹，最多保存5个点
    private ZiyanGyroGearUtil ziyanGyroGearUtil;

    private DeviceStudyConfigBean deviceStudyConfigBean;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gears_ziyan);
        ButterKnife.bind(this);
        setTitle("档位学习一");
        buttonG = new TextView[]{buttonG1, buttonG2, buttonG3, buttonG4, buttonG5, buttonG6};
        editMinX = new EditText[]{editMinX1, editMinX2, editMinX3, editMinX4, editMinX5, editMinX6};
        editMaxX = new EditText[]{editMaxX1, editMaxX2, editMaxX3, editMaxX4, editMaxX5, editMaxX6};
        editMinY = new EditText[]{editMinY1, editMinY2, editMinY3, editMinY4, editMinY5, editMinY6};
        editMaxY = new EditText[]{editMaxY1, editMaxY2, editMaxY3, editMaxY4, editMaxY5, editMaxY6};
        studyRun = new StudyRunnable[6];

        ziyanGyroGearUtil = ZiyanGyroGearUtil.getInstance(this);
        ziyanGyroGearUtil.getZiyanGearData(this);

        for (int i = 0; i < 6; i++) {
            studyRun[i] = new StudyRunnable(i + 1);
            studyRun[i].show();
        }
    }

    @Override
    protected void onDestroy() {
        for (int i = 0; i < 6; i++) {
            studyRun[i].isRunning = false;
        }
        super.onDestroy();
    }

    @OnClick({R.id.button_g1, R.id.button_g2, R.id.button_g3, R.id.button_g4, R.id.button_g5, R.id.button_g6, R.id.button_save, R.id.button_read, R.id.button_fix, R.id.button_reset})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.button_g1:
                study(1);
                break;
            case R.id.button_g2:
                study(2);
                break;
            case R.id.button_g3:
                study(3);
                break;
            case R.id.button_g4:
                study(4);
                break;
            case R.id.button_g5:
                study(5);
                break;
            case R.id.button_g6:
                study(6);
                break;
            case R.id.button_save:
                save();
                break;
            case R.id.button_read:
                read();
                break;
            case R.id.button_fix:
                fixRect();
                break;
            case R.id.button_reset:
                if (isReset) {
                    MessageBox.show(this, "已经重置差值！");
                } else {
                    for (int i = 0; i < 6; i++) {
                        editMinX[i].setText("");
                        editMaxX[i].setText("");
                        editMinY[i].setText("");
                        editMaxY[i].setText("");
                    }
                    if (StringUtils.isNotEmpty(gyroData)) {
                        String[] str = gyroData.split(";");
                        if (str.length == 8) {
                            resetX = 360f - Float.parseFloat(str[4]);
                            resetY = 360f - Float.parseFloat(str[5]);
                            isReset = true;
                            xys = new float[6][4];
                            deviceStudyConfigBean = LoadConfigApi.loadDeviceStudyConfig(this);
                            deviceStudyConfigBean.setXyGearReset(resetX + SEPARATOR + resetY);
                            deviceStudyConfigBean.setXyMechanicalGearStudy(ArrayConvertUtil.convertFloats2String(xys));
                            ParamConfigApi.saveDeviceStudyConfig(this, deviceStudyConfigBean);
                        }
                    }
                }
                break;
        }
    }

    private void study(int index) {
        if (!isReset) {
            MessageBox.show(this, "请先重置差值！");
            return;
        }
        if (index > 0 && index <= 6) {
            int studyIndex = getStudyRunningIndex();
            if (studyIndex == index) {
                studyRun[studyIndex - 1].isRunning = false;
            } else if (studyIndex > 0) {
                Toast.makeText(this, "正在学习其他档位，请先结束学习", Toast.LENGTH_SHORT).show();
            } else {
                String[] str = gyroData.split(";");
                float x = (360f - Float.parseFloat(str[4])) - resetX;
                float y = (360f - Float.parseFloat(str[5])) - resetY;
                xys[index - 1][0] = xys[index - 1][1] = x;
                xys[index - 1][2] = xys[index - 1][3] = y;
                new Thread(studyRun[index - 1]).start();
            }
        }
    }

    private int getStudyRunningIndex() {
        for (int i = 0; i < 6; i++) {
            if (studyRun[i].isRunning)
                return studyRun[i].index;
        }
        return 0;
    }

    private void refresh() {
        runOnUiThread(new Runnable() {
            @SuppressLint("SetTextI18n")
            @Override
            public void run() {
                String[] str = gyroData.split(";");
                float x = (360f - Float.parseFloat(str[4])) - resetX;
                float y = (360f - Float.parseFloat(str[5])) - resetY;
                textX.setText("X轴:" + x);
                textY.setText("Y轴:" + y);
                if (xPoints.size() < 5) {
                    xPoints.add(x);
                    yPoints.add(y);
                } else {
                    xPoints.remove(0);
                    yPoints.remove(0);
                    xPoints.add(x);
                    yPoints.add(y);
                }
                pointView.setxPoints(xPoints);
                pointView.setyPoints(yPoints);
                boolean hasGear = false;
                for (int i = 0; i < 6; i++) {
                    if (x >= xys[i][0] && x <= xys[i][1] && y >= xys[i][2] && y <= xys[i][3] && xys[i][0] != xys[i][1] && xys[i][2] != xys[i][3]) {
                        hasGear = true;
                        textG.setText("档位:" + (i + 1));
                        break;
                    }
                }
                if (!hasGear) {
                    textG.setText("档位:" + 0);
                }
            }
        });
    }

    /**
     * 修正区域
     */
    private void fixRect() {
        for (int i = 0; i < 6; i++) {
            if (studyRun[i].isNotReady()) {
                Toast.makeText(this, "尚未学习完成", Toast.LENGTH_SHORT).show();
                return;
            }
        }

        float x6 = xys[5][0];  //倒挡最小的X值
        float x1 = xys[0][0];  //1挡最小的X值
        if (x6 > x1) {  //倒挡最小的X值大于1挡最小的X值，则为上3下3挡
            //获取上面档位Y的最大值
            float upMaxY = xys[0][3];
            if (upMaxY < xys[2][3]) {
                upMaxY = xys[2][3];
            }
            if (upMaxY < xys[4][3]) {
                upMaxY = xys[4][3];
            }
            upMaxY += expandBoundaryValue;
            xys[0][3] = xys[2][3] = xys[4][3] = upMaxY;
            //获取上面档位Y的最小值
            float upMinY = xys[0][2];
            if (upMinY > xys[2][2]) {
                upMinY = xys[2][2];
            }
            if (upMinY > xys[4][2]) {
                upMinY = xys[4][2];
            }
            //获取下面档位Y的最大值
            float downMaxY = xys[1][3];
            if (downMaxY < xys[3][3]) {
                downMaxY = xys[3][3];
            }
            if (downMaxY < xys[5][3]) {
                downMaxY = xys[5][3];
            }
            //中心区域拓展的Y值（上面Y的最小值减去下面Y的最大值,取固定比例）
            float centerExpandY = (upMinY - downMaxY) * expandCenterY;
            upMinY -= centerExpandY;
            xys[0][2] = xys[2][2] = xys[4][2] = upMinY;
            downMaxY += centerExpandY;
            xys[1][3] = xys[3][3] = xys[5][3] = downMaxY;
            //获取下面档位Y的最小值
            float downMinY = xys[1][2];
            if (downMinY > xys[3][2]) {
                downMinY = xys[3][2];
            }
            if (downMinY > xys[5][2]) {
                downMinY = xys[5][2];
            }
            downMinY -= expandBoundaryValue;
            xys[1][2] = xys[3][2] = xys[5][2] = downMinY;
            //1挡和3挡的中间X值(1挡最大值加上（3挡最小值减去1档最大值的一半）)
            float delt13 = (xys[2][0] - xys[0][1]) / 2;
            float c13 = xys[0][1] + delt13;
            xys[0][1] = xys[2][0] = c13;
            xys[0][0] -= expandBoundaryValue;  //1挡左边向左移动相应的距离
            //3挡和5挡的中间X值(3挡最大值加上（5挡最小值减去3档最大值的一半）)
            float delt35 = (xys[4][0] - xys[2][1]) / 2;
            float c35 = xys[2][1] + delt35;
            xys[2][1] = xys[4][0] = c35;
            xys[4][1] += expandBoundaryValue;  //5挡右边向右移动相应的距离
            //2挡和4挡的中间X值(2挡最大值加上（4挡最小值减去2档最大值的一半）)
            float delt24 = (xys[3][0] - xys[1][1]) / 2;
            float c24 = xys[1][1] + delt24;
            xys[1][1] = xys[3][0] = c24;
            xys[1][0] -= expandBoundaryValue;  //2挡左边向左移动相应的距离
            //4挡和R挡的中间X值(4挡最大值加上（R挡最小值减去4档最大值的一半）)
            float delt4R = (xys[5][0] - xys[3][1]) / 2;
            float c4R = xys[3][1] + delt4R;
            xys[3][1] = xys[5][0] = c4R;
            xys[5][1] += expandBoundaryValue;  //R挡右边向右移动相应的距离
        } else {  //倒挡最小的X值小于1挡最小的X值，则为上4下2挡
            //获取上面档位Y的最大值
            float upMaxY = xys[0][3];
            if (upMaxY < xys[2][3]) {
                upMaxY = xys[2][3];
            }
            if (upMaxY < xys[4][3]) {
                upMaxY = xys[4][3];
            }
            if (upMaxY < xys[5][3]) {
                upMaxY = xys[5][3];
            }
            upMaxY += expandBoundaryValue;
            xys[0][3] = xys[2][3] = xys[4][3] = xys[5][3] = upMaxY;
            //获取上面档位Y的最小值
            float upMinY = xys[0][2];
            if (upMinY > xys[2][2]) {
                upMinY = xys[2][2];
            }
            if (upMinY > xys[4][2]) {
                upMinY = xys[4][2];
            }
            if (upMinY > xys[5][2]) {
                upMinY = xys[5][2];
            }

            //获取下面档位Y的最大值
            float downMaxY = xys[1][3];
            if (downMaxY < xys[3][3]) {
                downMaxY = xys[3][3];
            }
            //中心区域拓展的Y值（上面Y的最小值减去下面Y的最大值,取固定比例）
            float centerExpandY = (upMinY - downMaxY) * expandCenterY;
            upMinY -= centerExpandY;
            xys[0][2] = xys[2][2] = xys[4][2] = xys[5][2] = upMinY;
            downMaxY += centerExpandY;
            xys[1][3] = xys[3][3] = downMaxY;
            //获取下面档位Y的最小值
            float downMinY = xys[1][2];
            if (downMinY > xys[3][2]) {
                downMinY = xys[3][2];
            }
            downMinY -= expandBoundaryValue;
            xys[1][2] = xys[3][2] = downMinY;
            //R挡和1挡的中间X值(R挡最大值加上（1挡最小值减去R档最大值的一半）)
            float deltR1 = (xys[0][0] - xys[5][1]) / 2;
            float cR1 = xys[5][1] + deltR1;
            xys[5][1] = xys[0][0] = cR1;
            xys[5][0] -= expandBoundaryValue;  //R挡左边向左移动相应的距离
            //1挡和3挡的中间X值(1挡最大值加上（3挡最小值减去1档最大值的一半）)
            float delt13 = (xys[2][0] - xys[0][1]) / 2;
            float c13 = xys[0][1] + delt13;
            xys[0][1] = xys[2][0] = c13;
            //3挡和5挡的中间X值(3挡最大值加上（5挡最小值减去3档最大值的一半）)
            float delt35 = (xys[4][0] - xys[2][1]) / 2;
            float c35 = xys[2][1] + delt35;
            xys[2][1] = xys[4][0] = c35;
            xys[4][1] += expandBoundaryValue;  //5挡右边向右移动相应的距离
            //2挡和4挡的中间X值(2挡最大值加上（4挡最小值减去2档最大值的一半）)
            float delt24 = (xys[3][0] - xys[1][1]) / 2;
            float c24 = xys[1][1] + delt24;
            xys[1][1] = xys[3][0] = c24;
            xys[1][0] -= expandBoundaryValue;  //2挡左边向左移动相应的距离
            xys[3][1] += expandBoundaryValue;  //4挡右边向右移动相应的距离
        }

        for (int i = 0; i < 6; i++) {
            studyRun[i].show();
        }
    }

    private void save() {
        for (int i = 0; i < 6; i++) {
            if (studyRun[i].isNotReady()) {
                Toast.makeText(this, "尚未学习完成", Toast.LENGTH_SHORT).show();
                return;
            }
        }
        deviceStudyConfigBean = LoadConfigApi.loadDeviceStudyConfig(this);
        deviceStudyConfigBean.setXyMechanicalGearStudy(ArrayConvertUtil.convertFloats2String(xys));
        ParamConfigApi.saveDeviceStudyConfig(this, deviceStudyConfigBean);
        MessageBox.show(this, "保存成功");
        ziyanGyroGearUtil.resetParamValue();
    }

    private void read() {
        String reset = LoadConfigApi.loadDeviceStudyConfig(this).getXyGearReset();
        if (StringUtils.isNotEmpty(reset)) {
            String[] str = reset.split(SEPARATOR);
            resetX = Float.parseFloat(str[0]);
            resetY = Float.parseFloat(str[1]);
        }

        String data = LoadConfigApi.loadDeviceStudyConfig(this).getXyMechanicalGearStudy();
        if (StringUtils.isNotEmpty(data)) {
            xys = ArrayConvertUtil.convertString2Floats(data, 6, 4);
        }
        for (int i = 0; i < 6; i++) {
            studyRun[i].show();
        }
    }

    @Override
    public void onZiyanData(String data) {
        gyroData = data;
        refresh();
    }


    private class StudyRunnable implements Runnable {

        private boolean isRunning;
        private int index;

        StudyRunnable(int index) {
            this.isRunning = false;
            this.index = index;
        }

        @Override
        public void run() {
            isRunning = true;
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    buttonG[index - 1].setText("结束");
                }
            });
            while (isRunning) {
                String[] str = gyroData.split(";");
                float x = (360f - Float.parseFloat(str[4])) - resetX;
                float y = (360f - Float.parseFloat(str[5])) - resetY;
                if (xys[index - 1][0] > x) xys[index - 1][0] = x;
                if (xys[index - 1][1] < x) xys[index - 1][1] = x;
                if (xys[index - 1][2] > y) xys[index - 1][2] = y;
                if (xys[index - 1][3] < y) xys[index - 1][3] = y;
                show();
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    buttonG[index - 1].setText("学习");
                }
            });
            isRunning = false;
            System.out.println("hong ++++++++++ StudyRunnable finish: " + index);
        }

        private void show() {
            pointView.setStudy1Rect(index - 1, xys[index - 1][0], xys[index - 1][1], xys[index - 1][2], xys[index - 1][3]);

            runOnUiThread(new Runnable() {
                @SuppressLint("SetTextI18n")
                @Override
                public void run() {
                    editMinX[index - 1].setText("" + xys[index - 1][0]);
                    editMaxX[index - 1].setText("" + xys[index - 1][1]);
                    editMinY[index - 1].setText("" + xys[index - 1][2]);
                    editMaxY[index - 1].setText("" + xys[index - 1][3]);
                }
            });
        }

        private boolean isNotReady() {
            return isRunning || !(xys[index - 1][0] < xys[index - 1][1] && xys[index - 1][2] < xys[index - 1][3]);
        }
    }
}
